package com.sp.objectserver.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.sp.objectserver.entry.BaseEntry;
import com.sp.objectserver.server.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


@Slf4j
@RestController
public class BaseController {

    @Resource
    private WebSocketServer webSocketServer;


    @RequestMapping("com/list")
    public Map<String, Object> page() {
        SerialPort[] ports = SerialPort.getCommPorts();//查找所有串口
        HashMap<String, Object> listHashMap = new HashMap<>();
        ArrayList<String> strings = new ArrayList<>();
        for (SerialPort port : ports) {
            strings.add(port.getDescriptivePortName());
            log.info("活动的COM端口名称{}", port.getDescriptivePortName());
        }
        listHashMap.put("data", strings);
        listHashMap.put("code", 20000);
        listHashMap.put("msg", "查询成功");
        return listHashMap;
    }


    @RequestMapping("com/breakHandle")
    public Map<String, Object> breakHandle(@RequestParam("name") String name) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("data", null);
        hashMap.put("code", 20000);
        SerialPort[] ports = SerialPort.getCommPorts();
        for (SerialPort serialPort : ports) {
            if (serialPort.getDescriptivePortName().equals(name)) {
                serialPort.closePort();
            }
        }
        return hashMap;
    }


    @RequestMapping("com/excute")
    public Map<String, Object> excute(@RequestParam("serialPort") String name) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("data", null);
        hashMap.put("code", 20000);
        SerialPort[] ports = SerialPort.getCommPorts();//查找所有串口
        for (SerialPort serialPort : ports) {
            if (serialPort.getDescriptivePortName().equals(name)) {
                serialPort.setBaudRate(9600);//设置波特率为112500
                serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);//设置超时
                serialPort.setRTS();//设置RTS。也可以设置DTR
                serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//设置串口的控制流，可以设置为disabled，或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等
                serialPort.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);//一次性设置所有的串口参数，第一个参数为波特率，默认9600；第二个参数为每一位的大小，默认8，可以输入5到8之间的值；第三个参数为停止位大小，只接受内置常量，可以选择(ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS)；第四位为校验位，同样只接受内置常量，可以选择 NO_PARITY, EVEN_PARITY, ODD_PARITY, MARK_PARITY,SPACE_PARITY。
                if (!serialPort.openPort()) {
                    hashMap.put("msg", "串口" + name + "已经是开启状态");
                    return hashMap;
                } else {

                    serialPort.addDataListener(new SerialPortDataListener() {//添加监听器。由于该监听器有两个函数，无法使用Lambda表达式
                        @Override
                        public int getListeningEvents() {
                            // TODO Auto-generated method stub
                            return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要监听的事件类型，以供回调函数使用。可发回的事件包括：SerialPort.LISTENING_EVENT_DATA_AVAILABLE，SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分别对应有数据在串口（不论是读的还是写的），有数据写入串口，从串口读取数据。如果AVAILABLE和RECEIVED同时被监听，优先触发RECEIVED
                        }

                        @Override
                        public void serialEvent(SerialPortEvent event) {//事件处理函数
                            // TODO Auto-generated method stub
                            StringBuilder data = new StringBuilder();
                            ArrayList<String> strings = new ArrayList<>();
                            if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
                                return;//判断事件的类型
                            }
                            while (serialPort.bytesAvailable() != 0) {
                                byte[] newData = new byte[1024];
                                int numRead = serialPort.readBytes(newData, newData.length);
                                String newDataString = new String(newData, 0, numRead, Charset.forName("GBK"));
                                data.append(newDataString);
                            }
                            String string = data.toString();
                            String[] split = string.split("\n");
                            BaseEntry baseEntry = new BaseEntry();

                            for (String s : split) {
                                int l = 0;
                                for (int i = 1; i < s.length(); i++) {
                                    if ((s.charAt(i) != ' ' && s.charAt(i - 1) == ' ') || i == s.length() - 1) {
                                        if (l != 0) {
                                            strings.add(s.substring(l, i));
                                        }
                                        l = i;
                                    }
                                }
                            }
                            baseEntry.setLocalDate(strings.get(0));
                            baseEntry.setLocalTime(strings.get(1));
                            baseEntry.setWeight(strings.get(2));
                            baseEntry.setUnit(strings.get(3));
                            String s = "";
                            ObjectMapper objectMapper = new ObjectMapper();
                            try {
                                s = objectMapper.writeValueAsString(baseEntry);
                            } catch (JsonProcessingException e) {
                                throw new RuntimeException(e);
                            }
                            log.info("接收数据{}", baseEntry);
                            webSocketServer.sendOneMessage("1", s);
                            hashMap.put("msg", "和串口" + name + "连接成功");
                        }
                    });
                }
            }
        }
        return hashMap;
    }
}
